package uform.model.value;

import thx.validation.IValidator;
import thx.validation.DateGranularityRangeValidator;
import thx.validation.EmailValidator;
import thx.validation.IncrementValidator;
import thx.validation.RangeValidator;
import thx.validation.SingleLineValidator;
import thx.validation.StringLengthValidator;
import thx.validation.UrlValidator;
import uform.util.DateGranularity;

class Value
{
	public static function bool()
	{
		return new BoolType();
	}
	
	public static function date(?min : Date, ?max : Date)
	{
		return createDateType(Day, min, max);
	}
	
	public static function year(?min : Date, ?max : Date)
	{
		return createDateType(Year, min, max);
	}
	
	public static function month(?min : Date, ?max : Date)
	{
		return createDateType(Month, min, max);
	}
	
	public static function hour(?min : Date, ?max : Date)
	{
		return createDateType(Hour, min, max);
	}
	
	public static function minute(?min : Date, ?max : Date)
	{
		return createDateType(Minute, min, max);
	}
	
	public static function second(?min : Date, ?max : Date)
	{
		return createDateType(Second, min, max);
	}
	
	public static function email(validateDomain = true, minLength = 0, ?maxLength : Int)
	{
		return createStringType(minLength, maxLength).addValidator(new EmailValidator(validateDomain));
	}
	
   	public static function string(minLength = 0, ?maxLength : Int, multiline = false)
	{
		var type = createStringType(minLength, maxLength);
		if (!multiline)
			type.addValidator(new SingleLineValidator());
		return type;
	}
	
   	public static function url(minLength = 0, ?maxLength : Int)
	{
		return createStringType(minLength, maxLength).addValidator(new UrlValidator());
	}
	
	public static function password(minLength = 0, ?maxLength : Int)
	{
		return createStringType(minLength, maxLength).addMeta("input-type", "password");
	}
	
	public static function file(minLength = 0, ?maxLength : Int, ?mimeTypes : Array<String>)
	{
		var type = createStringType(minLength, maxLength).addMeta("input-type", "file");
		if (null != mimeTypes)
			type.addMeta("mime-types", mimeTypes);
		return type;
	}
	
	public static function float(?min : Float, ?max : Float, minInclusive = true, maxInclusive = true)
	{
		var type = new FloatType();
		if (null != min || null != max || null != minInclusive || null != maxInclusive)
			type.addValidator(new RangeValidator(min, max, minInclusive, maxInclusive));
		return type;
	}
	
	public static function int(?min : Float, ?max : Float, minInclusive = true, maxInclusive = true)
	{
		var type = new IntType();
		if (null != min || null != max || null != minInclusive || null != maxInclusive)
			type.addValidator(new RangeValidator(min, max, minInclusive, maxInclusive));
		return type;
	}
	
	static function createDateType(granularity : DateGranularity, min : Null<Date>, max : Null<Date>)
	{
		var type = new DateType(granularity);
		if (null != min || null != max)
			type.addValidator(new DateGranularityRangeValidator(granularity, min, max));
		return type;
	}
	
	static function createStringType(minLength : Null<Int>, maxLength : Null<Int>)
	{
		var type = new StringType();
		if (null != minLength || null != maxLength)
			type.addValidator(new StringLengthValidator(minLength, maxLength));
		return type;
	}
}